Skip to content

Django ORM

用法

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'PORT': 'PORT',
        'HOST': 'HOST',
        'NAME': 'NAME,
        'USER': 'USER,
        'PASSWORD': 'PASSWORD',
        'CONN_MAX_AGE': 60, 
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
            'charset': 'utf8mb4',
        }
    }
}

连接

一个请求一个连接

一个request内对一个DB的请求共用一个连接。连接默认在reqeust结束后关闭,但是可以设置连接保留时长(CONN_MAX_AGE),在时长内,请求结束后,连接会保留,被下一个请求复用。对于某些微服来说,大部分接口都需要访问同一个db实例(例如order),可以设置保留时长,这样,一个线程处理的多个请求,可以共用一个数据库连接。

lazy connect

django对于数据库操作都是懒加载的,只有在首次发起查询时才开始建立连接。

users = User.objects.filter(removed=False)  # 这里不会发起连接

for user in users:  # 在users被首次迭代的时候,发起DB连接
    print(user.name)

事务

默认autocommit

官方的解释,如果默认开启事务,处理提交和回滚是不方便的,因此django ORM默认行为是自动提交。这个也好理解,自动提交满足大部分的应用场景,并且代码编写方便。

显式开启事务

django提供了很多的方式处理事务。支持利用context manager来方便地使用事务。 上下文管理器进入时开启事务,结束后自动提交,如果事务内发生错误,自动回滚。

def post(request):
    with transaction.atomic():
        # This code executes inside a transaction.
        do_more_stuff()

装饰器开启事务

# open a transaction
@transaction.atomic
def viewfunc(request):

    a.save()
    # transaction now contains a.save()

    sid = transaction.savepoint()

    b.save()
    # transaction now contains a.save() and b.save()

    if want_to_keep_b:
        transaction.savepoint_commit(sid)
        # open transaction still contains a.save() and b.save()
    else:
        transaction.savepoint_rollback(sid)
        # open transaction now contains only a.save()

请求即事务

在django DB配置中ATOMIC_REQUESTS设为True,可以将整个请求自动放到事务里执行,请求正常结束后自动提交,请求处理出错自动回滚。

用法